import logging
import importlib
import sqlalchemy
from typing import Optional
from sqlalchemy import inspect, text
from app.db.factory import DBFactoryManager, Base
from app.core.config import settings
from app.crud.user import user as crud_user
from app.schemas.user import UserCreate

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def create_database_if_not_exists(db_type: str) -> None:
    """检查并创建数据库（如果不存在）
    
    根据不同的数据库类型，使用不同的方法创建数据库
    
    Args:
        db_type: 数据库类型
    """
    if db_type == "sqlite":
        # SQLite会自动创建文件，不需要额外操作
        logger.info("SQLite数据库将在首次使用时自动创建")
        return
    
    try:
        if db_type == "mysql":
            # 从连接URI中提取数据库名称和连接信息
            uri = settings.MYSQL_DATABASE_URI
            db_name = settings.MYSQL_DB
            # 创建不带数据库名的连接URI
            server_uri = f"mysql+pymysql://{settings.MYSQL_USER}:{settings.MYSQL_PASSWORD}@{settings.MYSQL_SERVER}/"
            
            # 连接到MySQL服务器（不指定数据库）
            engine = sqlalchemy.create_engine(server_uri)
            with engine.connect() as conn:
                # 检查数据库是否存在
                result = conn.execute(text(f"SHOW DATABASES LIKE '{db_name}'"))
                if not result.fetchone():
                    logger.info(f"创建MySQL数据库: {db_name}")
                    conn.execute(text(f"CREATE DATABASE {db_name}"))
                    conn.commit()
                else:
                    logger.info(f"MySQL数据库 {db_name} 已存在")
        
        elif db_type == "postgresql":
            # 从连接URI中提取数据库名称和连接信息
            db_name = settings.POSTGRES_DB
            # 创建连接到默认数据库的URI
            server_uri = f"postgresql://{settings.POSTGRES_USER}:{settings.POSTGRES_PASSWORD}@{settings.POSTGRES_SERVER}/postgres"
            
            # 连接到PostgreSQL服务器（使用默认的postgres数据库）
            engine = sqlalchemy.create_engine(server_uri)
            with engine.connect() as conn:
                # 设置自动提交，因为CREATE DATABASE不能在事务中执行
                conn.execution_options(isolation_level="AUTOCOMMIT")
                # 检查数据库是否存在
                result = conn.execute(text(f"SELECT 1 FROM pg_database WHERE datname = '{db_name}'"))
                if not result.fetchone():
                    logger.info(f"创建PostgreSQL数据库: {db_name}")
                    conn.execute(text(f"CREATE DATABASE {db_name}"))
                else:
                    logger.info(f"PostgreSQL数据库 {db_name} 已存在")
    
    except Exception as e:
        logger.error(f"创建数据库时出错: {str(e)}")
        # 在这里我们只记录错误，但不抛出异常，让程序继续尝试连接
        # 这样即使没有创建数据库的权限，如果数据库已存在，程序仍然可以正常工作

def check_tables_exist(engine) -> bool:
    """检查数据库中是否存在表
    
    Args:
        engine: SQLAlchemy引擎实例
        
    Returns:
        bool: 如果存在至少一个表则返回True，否则返回False
    """
    inspector = inspect(engine)
    tables = inspector.get_table_names()
    return len(tables) > 0

def create_superuser(factory: DBFactoryManager) -> None:
    """创建超级管理员用户
    
    检查数据库中是否存在超级管理员用户，如果不存在则创建一个
    用户名和密码都为'admin'的超级管理员账户
    
    Args:
        factory: 数据库工厂实例
    """
    # 创建数据库会话
    session_local = factory.create_session_local()
    db = session_local()
    
    try:
        # 检查是否已存在超级管理员用户
        # 使用SQLAlchemy ORM查询语法
        from app.models.user import User
        superuser = db.query(User).filter(User.is_superuser == True).first()
        
        if not superuser:
            logger.info("创建超级管理员用户: admin")
            # 创建超级管理员用户对象
            admin_user = UserCreate(
                email="admin@example.com",
                username="admin",
                password="admin",
                is_superuser=True,
                full_name="Administrator"
            )
            # 使用CRUD操作创建用户
            crud_user.create(db, obj_in=admin_user)
            logger.info("超级管理员用户创建成功")
        else:
            logger.info("超级管理员用户已存在，跳过创建")
    except Exception as e:
        logger.error(f"创建超级管理员用户时出错: {str(e)}")
    finally:
        db.close()

def init_db(db_type: Optional[str] = None) -> None:
    """初始化数据库
    
    根据配置初始化数据库连接工厂，并创建所有表
    如果数据库不存在，则先创建数据库
    如果表不存在，则创建所有表
    
    Args:
        db_type: 数据库类型，如不提供则使用配置中的DB_TYPE
    """
    # 使用配置中的数据库类型或传入的类型
    db_type = db_type or settings.DB_TYPE
    logger.info(f"初始化数据库，类型: {db_type}")
    
    # 检查并创建数据库（如果不存在）
    create_database_if_not_exists(db_type)
    
    # 获取数据库工厂
    factory = DBFactoryManager.get_factory(db_type)
    
    # 创建引擎
    engine = factory.create_engine()
    
    # 检查表是否存在
    tables_exist = check_tables_exist(engine)
    
    # 导入所有模型以确保它们被注册到Base.metadata
    import app.models
    
    # 如果表不存在，则创建所有表
    if not tables_exist:
        logger.info("创建数据库表")
        Base.metadata.create_all(bind=engine)
    else:
        logger.info("数据库表已存在，跳过创建")
    
    # 创建超级管理员用户
    create_superuser(factory)